package Q17_22_Word_Transformer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import CtCILibrary.HashMapList;
public class QuestionB {
/* find path to transform startWord into endWord. */
public static LinkedList<String> transform(String start, String stop, String[] words) {
HashMapList<String, String> wildcardToWordList = createWildcardToWordMap(words);
HashSet<String> visited = new HashSet<String>();
return transform(visited, start, stop, wildcardToWordList);
}
/* Do a depth-first search from start to stop, traveling through each word that is one edit away. */
public static LinkedList<String> transform(HashSet<String> visited, String start, String stop, HashMapList<String, String> wildcardToWordList) {
if (start.equals(stop)) {
LinkedList<String> path = new LinkedList<String>();
path.add(start);
return path;
} else if (visited.contains(start)) {
return null;
}
visited.add(start);
ArrayList<String> words = getValidLinkedWords(start, wildcardToWordList);
for (String word : words) {
LinkedList<String> path = transform(visited, word, stop, wildcardToWordList);
if (path != null) {
path.addFirst(start);
return path;
}
}
return null;
}
/* Insert words in dictionary into mapping from wildcard form -> word. */
public static HashMapList<String, String> createWildcardToWordMap(String[] words) {
HashMapList<String, String> wildcardToWords = new HashMapList<String, String>();
for (String word : words) {
ArrayList<String> linked = getWildcardRoots(word);
for (String linkedWord : linked) {
wildcardToWords.put(linkedWord, word);
}
}
return wildcardToWords;
}
/* Get list of wildcards associated with word. */
public static ArrayList<String> getWildcardRoots(String w) {
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < w.length(); i++) {
String word = w.substring(0, i) + "_" + w.substring(i + 1);
words.add(word);
}
return words;
}
/* Return words that are one edit away. */
public static ArrayList<String> getValidLinkedWords(String word, HashMapList<String, String> wildcardToWords) {
ArrayList<String> wildcards = getWildcardRoots(word);
ArrayList<String> linkedWords = new ArrayList<String>();
for (String wildcard : wildcards) {
ArrayList<String> words = wildcardToWords.get(wildcard);
for (String linkedWord : words) {
if (!linkedWord.equals(word)) {
linkedWords.add(linkedWord);
}
}
}
return linkedWords;
}
public static void main(String[] args) {
String[] words = {"maps", "tan", "tree", "apple", "cans", "help", "aped", "pree", "pret", "apes", "flat", "trap", "fret", "trip", "trie", "frat", "fril"};
LinkedList<String> list = transform("tree", "flat", words);
if (list == null) {
System.out.println("No path.");
} else {
System.out.println(list.toString());
}
}
}